package com.zbkj.admin.boot.config;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.*;

public class RecursiveTaskDemo {

    private static final ExecutorService executor = new ThreadPoolExecutor(2, 3, 10, TimeUnit.SECONDS, new LinkedBlockingQueue(10));
    private static final int totalRow = 5300000;
    private static final int splitRow = 1000;

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        long start = System.currentTimeMillis();
        //先循环生成待待处理集合
        List<Integer> list = new ArrayList<>(totalRow);
        for (int i = 0; i < totalRow; i++) {
            list.add(i);
        }
        //计算出需要创建的任务数
        int loopNum = (int)Math.ceil((double)totalRow/splitRow);
        ForkJoinPool pool = new ForkJoinPool(loopNum);
        ForkJoinTask<List> submit = pool.submit(new MyTask(list, 0, list.size()));

        List<List<Integer>>list1=new ArrayList<>();
        list1.add(submit.get());
        System.err.println("执行任务消耗了 ：" + (System.currentTimeMillis() - start) + "毫秒");
        System.out.println("結果["+list.size()+"]===");
    }
    //继承RecursiveTask
    static class MyTask extends RecursiveTask<List> {
        private List<Integer> list;
        private Iterator iterator;
        private int startRow;
        private int endRow;

        public MyTask(List<Integer> list, int startRow, int endRow) {
            this.list = list;
            this.startRow = startRow;
            this.endRow = endRow;
        }

        /**
         * 递归处理数据，计算
         * @return
         */
        @Override
        protected List compute() {
            if (endRow - startRow <= splitRow) {
                List<Integer> ret = new ArrayList<>();
                for (int i = startRow; i < endRow; i++) {

                    //递归处理数据
                    ret.add(list.get(i));
                }
//                System.out.println(Thread.currentThread().getName());
                return ret;
            }
            int loopNum = (int)Math.ceil((double)totalRow/splitRow);
            int startRow = 0;
            List<MyTask> myTaskList = new ArrayList<>();
            for (int i = 0; i < loopNum; i++) {
                if (startRow > totalRow) {
                    break;
                }
                int endRow = Math.min(startRow + splitRow, totalRow);
                myTaskList.add(new MyTask(list, startRow, endRow));
                startRow += splitRow;
            }
            //调用不同线程上独立执行的任务
            invokeAll(myTaskList);
            List<Integer> ret = new ArrayList<>();
            //归并
            for (MyTask myTask : myTaskList) {
                ret.addAll(myTask.join());
            }
            return ret;
        }
    }
}